        TITL DAI FIRMWARE 0EA40-0EC15  V1.0  Rev.1
        ORG   :EA40
*
*
*
****************************
* part of RUN TALK (0E67B) *
****************************
*
* Sets oscillator volumes.
*
* Entry: A:  New volume.
*        HL: Address POROM/POR1M.
*
MPT48   MOV   M,A       Update POR0M/POR1M
        LXI   D,:FA70
        DAD   D         HL= POR0/POR1
        MOV   M,A       Update osc.volume
        POP   H         Get parameter pntr
RTK55   INX   H         Pnts to next code
        JMP   :CD67     Handle next code
*
        DATA  :FF
        DATA  :FF
        DATA  :FF
        DATA  :FF
        DATA  :FF
*
*************************
* RUN basicfunction ABS *
*************************
*
RABS    RST   4         MFABS
        DATA  :18
        RET
*
**************************
* RUN basicfunction ALOG *
**************************
*
RALOG   RST   4         MALOG
        DATA  :30
        RET
*
*************************
* RUN basicfunction EXP *
*************************
*
REXP    RST   4         MEXP
        DATA  :2A
        RET
*
**************************
* RUN basicfunction FRAC *
**************************
*
RFRAC   RST   4         MFRAC
        DATA  :21
        RET
*
*************************
* RUN basicfunction LOG *
*************************
*
RLOG    RST   4         MLOG
        DATA  :27
        RET
*
**************************
* RUN basicfunction LOGT *
**************************
*
RLOGT   RST   4         MLOGT
        DATA  :2D
        RET
*
*************************
* RUN basicfunction SQR *
*************************
*
RSQR    RST   4         MSQR
        DATA  :33
        RET
*
*************************
* RUN basicfunction SIN *
*************************
*
RSIN    RST   4         MSIN
        DATA  :36
        RET
*
*************************
* RUN basicfunction COS *
*************************
*
RCOS    RST   4         MCOS
        DATA  :39
        RET
*
*************************
* RUN basicfunction TAN *
*************************
*
RTAN    RST   4         MTAN
        DATA  :3C
        RET
*
**************************
* RUN basicfunction ASIN *
**************************
*
RASIN   RST   4         MASIN
        DATA  :3F
        RET
*
**************************
* RUN basicfunction ACOS *
**************************
*
RACOS   RST   4         MACOS
        DATA  :42
        RET
*
*
**************************
* RUN basicfunction ATAN *
**************************
*
RATN    RST   4         MATAN
        DATA  :45
        RET
*
**************************
* RUN basicfunction STR$ *
**************************
*
* Converts a FPT number into a string.
*
RSTR    CALL  :CE9B     Convert MACC for FPT output
 REM string in DECBUF
        NOP
        NOP
        NOP
RST20   LHLD  :C033     Get addr DECBUF
        MVI   E,:01     Pretend it is a variable
        RET
*
**************************
* RUN basicfunction HEX$ *
**************************
*
* Converts a INT number into an equivalent string.
*
RHEX    CALL  :E808     Eval expr, result in MACC
        CALL  :C02D     Conv. MACC to HEX for output
        JMP   :EA7D     Get addr DECBUF, pretend it
 REM is a variable
*
*************************
* RUN basicfunction SPC *
*************************
*
* Returns a string of a number of spaces.
* From SPC10 used by TAB if DOUTC<>0.
*
RSPC    CALL  :E71D     Get nr of spaces in A
 REM
* Entry from RTAB:
 REM
SPC10   CALL  :D18B     Get place in heap for string
 REM of spaces
        PUSH  H         Save pntr to heap
SPC20   ORA   A
        JZ    :EA9E     Jump if ready
        INX   H
        MVI   M,:20     Space into heap
        DCR   A
        JMP   :EA93     Next space
SPC30   POP   H         HL pnts to start string
        JMP   :EADF     Pretend it is a temp string
*
*************************
* RUN basicfunction TAB *
*************************
*
* Returns a string of spaces to move cursor to a
* given character position (only to the right).
* Works only if output switch DOUTC=0, else it
* returns one space only.
*
RTAB    CALL  :CE60     Get nr of tabs in L,
 REM DOUTC in A
        ORA   A         Check output direction
        MVI   A,:01     Init 1 space
        JNZ   :EA8F     Jump if DOUTC<>0
        MOV   A,L       Get nr of tabs
        NOP
        NOP
        RST   5         Ask cursor pos and size
        DATA  :0C       char screen
        SUB   L         Calc nr of spaces reqd
        JNC   :EA8F     Run SPC if not past tab pos
        XRA   A         If past TAB:
        JMP   :EA8F     Run SPC for no spaces
*
**************************
* RUN basicfunction CURX *
**************************
*
RCURX   RST   5         Ask cursor pos and size
        DATA  :0C       char screen
        MOV   A,L       X-coord in A
        JMP   :EB7C     and into MACC
*
**************************
* RUN basicfunction CURY *
**************************
*
RCURY   RST   5         Ask cursor pos and size
        DATA  :0C       char screen
        MOV   A,H       Y-coord in A
        JMP   :EB7C     and in MACC
*
*************************
* RUN basicfunction LEN *
*************************
*
* Given a string, returns length of the string.
*
RLEN    CALL  :E791     Eval string expr
RLE10   MOV   A,M       Get length in A
        JMP   :EB7C     and into MACC
*
*************************
* RUN basicfunction ASC *
*************************
*
* Given a string, returns ASCII value of 1st char.
*
RASC    CALL  :E791     Eval string expr
        MOV   A,M       Get length in A
        JMP   :CF7E     Check if length is 0; get
 REM 1st char in MACC if not
*
**************************
* RUN basicfunction CHR$ *
**************************
*
RCHR    CALL  :E71D     Get argument value in A
        PUSH  PSW       Save it
        MVI   A,:01
        CALL  :D18B     Find place in heap for
 REM a 1-byte string
        POP   PSW       Get argument
        INX   H
        MOV   M,A       Store it in Heap
        DCX   H         Pnts to length byte
 REM
* Entry from 'SPC':
 REM
RCR10   MVI   E,:02     Status: temporary
        RET
*
***************************
* RUN basicfunction LEFT$ *
***************************
*
* Given a string, returns a number of characters
* from the left end.
*
RLEFT   CALL  :E79D     Eval string expr
        PUSH  H         Save string pntr
        PUSH  D
        CALL  :EB1D     Reqd length in A
        MVI   D,:00
RLF10   MOV   E,A       Length in DE
RLF20   CALL  :D14F     Extract substring
        JNC   :DA15     Evt. run error 'NUMBER OUT
 REM OF RANGE'
        POP   D
        XTHL
        MOV   A,E       Get status
        CPI   :02       Temporary?
        CZ    :D187     Then clear heap entry
        POP   H
        MVI   E,:02     Status temporary
        RET
*
****************************
* RUN basicfunction RIGHT$ *
****************************
*
* Extracts a number of characters from the
* right end of a given string.
*
RRIGHT  CALL  :E79D     Eval string expr
        PUSH  H         Save string pntr
        PUSH  D
        CALL  :EB1D     Get length substring
        MOV   E,A       in E
        MOV   A,M       Get total string length
        SUB   E
        MOV   D,A       Startposition in D
        JMP   :EAED     Extract substring
*
**************************
* RUN basicfunction MID$ *
**************************
*
RMID    CALL  :E79D     Eval string expr
        PUSH  H         Save string pntr
        PUSH  D
        CALL  :EB1D     Get startposition
        MOV   D,A       in D
        CALL  :E71D     Get length in A
        JMP   :EAEC     Extract substring
*
******************************
* GET VALUE OF ARGUMENT IN A *
******************************
*
* Exit: DEHL preserved.
*
REXIK   PUSH  H
        PUSH  D
        CALL  :E71D     Get value of argument in A
        POP   D
        POP   H
        RET
*
*************************
* RUN basicfunction VAL *
*************************
*
* Takes a string and converts it to a FPT number.
*
RVAL    CALL  :E791     Eval string expr
        PUSH  B
SUEPT   MOV   A,M       Length of string in A
        STA   :0134     and in EFECT
        INX   H         HL pnts to 1st string byte
        SHLD  :0132     Addr into EFEPT
        MVI   C,:00     Char count
        LXI   H,:0135
        MVI   M,:01     Input from string
        CALL  :C01E     encode FPT number into MACC
        DCR   M         Input from keyboard
        MVI   A,:0A     If over/underflow: run
        JNC   :D9F5     error 'INVALID NUMBER'
        POP   B
        RET
*
*************************
* RUN basicfunction FRE *
*************************
*
* Returns a INT given size of free RAM space.
* Result in MACC.
* FR2BY: Also used to copy HL into MACC.
*
* Exit: BC preserved, AFDEHL corrupted.
*
RFRE    CALL  :EB51     Calc free RAM space in HL
FR2BY   XRA   A
        PUSH  B
        PUSH  D
        MOV   C,H       ) Free space in CD
        MOV   D,L       )
        MOV   B,A       A,B=0
        RST   4         Copy reg A,B,C,D into MACC
        DATA  :12
        POP   D
        POP   B
        RET
*
****************************
* CALCULATE FREE RAM SPACE *
****************************
*
* Exit: HL: Free RAM space.
*       DE: STBUSE.
*       ABC preserved, F corrupted.
*
SIZE    LHLD  :02A3     Get end symtab
        XCHG            in DE
        LHLD  :02A5     Get bottom screen RAM
        CALL  :DE1A     Calc. free space in HL
        RET
*
**************************
* RUN basicfunction FREQ *
**************************
*
* Given a frequency in Hz, returns a period in
* 'oscillator cycles' (INT).
*
* Entry: MACC: Value for freq.
* Exit:  BC preserved, AFDEHL corrupted.
*
RFREQ   LXI   H,:0129   Startaddr scratch area for
 REM expression evaluation
        RST   4         Copy reqd freq to scratch
        DATA  :0F       area
        PUSH  H         Save startaddr scratch area
        LXI   H,:D0ED   Addr sound constant
        RST   4         Sound constant into MACC
        DATA  :0C
        POP   H         Get start scratch area
        RST   4         Calc sound const/reqd freq
        DATA  :09
        RST   4         Change it to INT
        DATA  :48
        PUSH  B
        RST   4         Copy result to reg A,B,C,D
        DATA  :15
        ORA   B         > 64K ? Then run error
        JNZ   :DA15     'NUMBER OUT OF RANGE'
        POP   B
        RET
*
*********************
* DATA - (not used) *
*********************
*
L0E235  DATA  :15       Sound constant
        DATA  :F4
        DATA  :24
        DATA  :00
*
**************************
* RUN basicfunction GETC *
**************************
*
* Gets one character from keyboard. Returns its
* ASCII value in MACC; 0 if no inputs.
* FR1BY: Also used to copy 1 byte into MACC.
*
RGETC   CALL  :D6BB     Scan keyboard, result in A
FR1BY   MOV   L,A       Result in L
        MVI   H,:00
        JMP   :EB46     Result into MACC
*
*************************
* RUN basicfunction INP *
*************************
*
* Reads a byte from a Real World address (DCE-bus).
*
RINP    CALL  :E71D     Get RW addr in A
        MOV   D,A       and in D
        CALL  :D8E0     Get input from DCE-bus
        MOV   A,E       Result in A
        JMP   :EB7C     Result into MACC
*
*************************
* RUN basicfunction INT *
*************************
*
* Returns a integer FPT value, just less than the
* FPT argument given.
* REMARK: Routine is wrong if -1 < nr < 0. Then
*         the result is -1 !
*
RINT    PUSH  B
        RST   4         Copy MACC to reg A,B,C,D
        DATA  :15
        POP   B
        RST   4         Change MACC to INT, and then
        DATA  :1E       to FPT
        LXI   H,:D0F1   Addr FPT(-1)
        ORA   A
        JP    :EB9C     Abort if positive
        RST   4         Add -1 if MACC negative
        DATA  :00
L0E239  RET
*
*********************
* DATA - (not used) *
*********************
*
L0E240  DATA  :81       FPT (-1)
        DATA  :80
        DATA  :00
        DATA  :00
*
****************************
* RUN basicfunction VARPTR *
****************************
*
RVPT    CALL  :E963     Get varptr in HL, T/L in A
        JMP   :EB46     Varptr into MACC
*
**************************
* RUN basicfunction XMAX *
**************************
*
RXMAX   CALL  :EBB4     Get max Y,X-coord graph area
        XCHG            Max X-coord in HL
        JMP   :EB46     and into MACC
*
**************************
* RUN basicfunction YMAX *
**************************
*
RYMAX   CALL  :EBB4     Get max Y,X-coord graph area
        JMP   :EB7C     Max Y-coord into MACC
*
******************************************
* GET MAX. Y,X-COORDINATES GRAPHICS AREA *
******************************************
*
* Exit: DE: Max. X-coordinate.
*       A:  Max. Y-coordinate.
*       BC preserved.
*
L0E245  LXI   H,:0000   ) Coord dot 0,0
        PUSH  B         )
        MOV   C,H       )
        RST   5         Ask colour of point and
        DATA  :27       size graphics screen
        JC    :E602     Evt run screen error
        MOV   A,B       Max Y-coord in A
        POP   B
        RET
*
*************************
* RUN basicfunction PDL *
*************************
*
* A given paddle channel is enabled. Counter 0 is
* set to FFFF. The counter is read over and over
* until it is counted out.
*
* Exit: BC updated, AFDEHL corrupted.
*
RPDL    MVI   A,:05
        CALL  :E743     Get paddle select (0-5)
        MOV   D,A       into D
        LDA   :0040     Get POROM
        ANI   :F8       ROM/cass.select only
        ORA   D         OR with paddle select
        ORI   :08       Paddle enable
        CALL  :D808     Load PORO/POROM
        PUSH  B
        MVI   A,:30
        LXI   B,:FC06   Addr 8253 cmd word
        STAX  B         Select ch.0, mode 0, 2 byte
        LXI   H,:FFFF
        SHLD  :FC00     Load counter ch.0
        LDA   :FD01     Get pdl timer trig impulse
 REM (Useless: A is cleared in
 REM 0EBE3)
PDL10   XCHG            DE = FFFF
        MVI   A,:00
        STAX  B         (FC06)=00: counter 0, latch
 REM operation
        LHLD  :FC00     Get contents counter 0
        CALL  :DE14     Compare HL-DE
        JC    :EBE2     Again if DE > HL
        CALL  :DE26     HL = 2-compl. of HL
        LXI   D,:FFCE   ) Substract 49
        DAD   D         )
        JC    :EBFC     If result negative
        LXI   H,:0000
PDL20   MOV   A,H
        ORA   A
        JZ    :EC06
        MVI   L,:FF
        NOP
        NOP
        NOP
PDL30   MVI   A,:36
        STAX  B         (FC06)=#36: Chan 0, mode 3
        LDA   :0040     Get PORO/POROM
        ANI   :F0       Disable paddle operation
        CALL  :D806     Load PORO/POROM
        POP   B
        MOV   A,L       A=0 if result negative,
 REM else FF
        JMP   :EB7C     Move A into MACC
*
*
*
        END
